package cn.yunyichina.provider.pay.thread;

import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.PayService;
import cn.yunyichina.provider.framework.utils.UUIDUtil;
import cn.yunyichina.provider.iface.entity.base.EventVo;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.pay.OrderCheckedExceptionVo;
import cn.yunyichina.provider.iface.entity.pay.PaymentCheckSourceFileVo;
import cn.yunyichina.provider.pay.constant.MethodRouter;
import cn.yunyichina.provider.pay.entity.PaymentSetting;
import cn.yunyichina.provider.pay.service.CheckPaymentService;
import cn.yunyichina.provider.pay.service.impl.FinanceServiceImpl;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Callable;

/**
 * 对账线程处理
 * Created by JoeZ on 2016/10/31.
 */
public class PaymentCheckRunnable implements Callable<Response>{

    private String date;
    private PaymentSetting paymentSetting;
    private String orgId;
    private String orgName;
    private JSONObject jsonLog;

    private Logger logger = LoggerFactory.getLogger(PaymentCheckRunnable.class);

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static SimpleDateFormat YYYYMMDDHHMISS14 = new SimpleDateFormat("yyyyMMddHHmmss");

    private CheckPaymentService checkPaymentService = SpringContextHandler.getBean(CheckPaymentService.class);

    public PaymentCheckRunnable(PaymentSetting paymentSetting, String date , String orgId , String orgName,JSONObject jsonLog){
        this.paymentSetting = paymentSetting;
        this.date = date;
        this.orgId = orgId;
        this.orgName = orgName;
        this.jsonLog = jsonLog;
    }


    public Response call() throws Exception {
        return inputAndCheckPayments();
    }


    public Response inputAndCheckPayments(){
    	FinanceServiceImpl.thLogInfo.set(jsonLog);
    	boolean getDataFlag = false;
    	boolean inputAndCheckPaymentsFlag = false;
    	boolean exceptionFlag = false;
    	Map<String, Object> mapReturn = new HashMap<>();
    	
        Response response = new Response();
        Map<String, String> map = new HashMap<>();

        String publicKey = paymentSetting.getPublicKey();  //第三方支付公司公钥
        String privateKey = paymentSetting.getPrivateKey(); //支付私钥 alipayApp
        String payKey = paymentSetting.getPayKey(); //支付密钥 wechatApp
        String appId = paymentSetting.getPayAppId();
        Short payMode = paymentSetting.getPayMode();

        String count = null;
        response.setResult(orgId);

        map.put("orgId",orgId);
        map.put("orgName",orgName);
        map.put("appId",appId);
        map.put("date",date);
        if("2".equals(payMode.toString().substring(0,1)) && paymentSetting.getEnableFlag() == 1){
            map.put("publicKey",publicKey);
            map.put("privateKey",privateKey);
            try {
                //获取支付宝数据,并入库
                Response resp = PayService.callHumpFromInternal(MethodRouter.ALIPAY_CHECK_PAYMENT_PLATFORM, JSON.toJSONString(map));
                logger.info("alipay调用："+JsonUtils.toJsonString(resp));
                Map <String,String> amap = JSON.parseObject(resp.getResult(), Map.class);
                if (StringUtils.isNotBlank(resp.getResult())) {
                 	mapReturn = JsonUtils.parseObject(resp.getResult());
                }
                if(!"0".equals(resp.getResultCode()) && !"51002".equals(resp.getResultCode())){
                    logger.error(orgName + "拉取alipay账单失败！-- " + resp.getResultMessage());
                    getDataFlag = false;

                }else if("51002".equals(resp.getResultCode())){
                    logger.error(orgName + " -- " + resp.getResultCode() + resp.getResultMessage());
                    getDataFlag = true;
    
                }else{
                	getDataFlag = true;
                	 
                    count = amap.get("count");
                    List<OrderCheckedExceptionVo> exVos = new ArrayList<OrderCheckedExceptionVo>();
                    List<PaymentCheckSourceFileVo> payVos = new ArrayList<PaymentCheckSourceFileVo>();

                    long time = new Date().getTime() / 1000;
                    logger.info("<<<<< PaymentCheckRunnable."+ orgName +"开始时间:" + sdf.format(new Date()));

                    //当天账单根据订单号查询Order表
                    map = new HashMap<>();
                    map.put("pay_time",date);
                    map.put("pay_app_id",appId);
                    resp = checkPaymentService.getCheckPayment(JSON.toJSONString(map));
                    if("0".equals(resp.getResultCode())){
                        List<PaymentCheckSourceFileVo> vos = JsonUtils.parseArray(resp.getResult(), PaymentCheckSourceFileVo.class);
                        for (PaymentCheckSourceFileVo co : vos) {
                            map = new HashMap<>();
                            map.put("order_no", co.getOrderNo());
                            Response res = BaseService.callHumpFromInternal(MethodRouter.BASE_FIND_ORDER, JSON.toJSONString(map));
                            if("0".equals(res.getResultCode())){
                                map = JsonUtils.parseObject(res.getResult(), Map.class);
                                co.setPlatformId(map.get("platform_id"));
                                co.setPlatformName(map.get("platform_name"));
                                co.setPlatformCode(map.get("platform_code"));
                                co.setPlatformOrgAppCode(map.get("platform_org_app_code"));
                                co.setPlatformOrgAppName(map.get("platform_org_app_name"));
                                co.setOrgId(map.get("org_id"));
                                co.setOrgName(map.get("org_name"));
                                co.setOrgCode(map.get("org_code"));
                                payVos.add(co);
                            }else{
                                OrderCheckedExceptionVo orderException = new OrderCheckedExceptionVo();
                                orderException.setId(UUIDUtil.get32UUID());
                                orderException.setOrderNo(co.getOrderNo());
                                orderException.setOrgId(orgId);
                                orderException.setPayAppId(co.getPayAppId());
                                orderException.setPayTime(co.getPayTime());
                                orderException.setExceptionType((short) 1);
                                orderException.setExceptionReason(orgName + " 订单号：" + co.getOrderNo() + " 订单不存在！！");
                                orderException.setCreatedBy("三方对账平台");
                                orderException.setCreatedTime(sdf.format(new Date()));
                                exVos.add(orderException);
                                throw new RuntimeException(orgName + " 订单号：" + co.getOrderNo() + ",该订单在Order表不存在！！");
                            }
                        }
                    }

                    //执行修改数据
                    resp = checkPaymentService.updateCheckPayment(JSON.toJSONString(payVos));

                    if(exVos.size() > 0){
                        checkPaymentService.addCheckPaymentToException(JSON.toJSONString(exVos));
                    }

                    logger.info("<<<<< PaymentCheckRunnable."+ orgName +"结束时间:" + ((new Date().getTime() / 1000) - time));

                    if("0".equals(resp.getResultCode())){
                        logger.info(orgName + appId + "入库完毕！---alipay入库数："+ count +",返回信息：" + resp.getResultMessage());
                        inputAndCheckPaymentsFlag = true;
                    }
                    else {
                    	logger.error("updateCheckPayment异常");
                    }
                    
                }
            } catch (Exception e) {
            	exceptionFlag = true;
            	mapReturn.put("inputAndCheckPayments", "拉取alipay对账文件出现异常："+e.getMessage());
                logger.error("[PaymentCheckRunnable.checkPayments.alipay]" + orgName, e);
                //事件信息
                Map<String,Object> paramEvent = new HashMap<>();
                paramEvent.put("event_code", "CK_PULL_PAY_BILL");
                paramEvent.put("module_code", "CHECK_ACCOUNT");
                Response responseEvent = BaseService.callHumpFromInternal("yyt.base.event.get", JsonUtils.toJsonString(paramEvent));
                if (StringUtils.isNotBlank(responseEvent.getResult())) {
                    EventVo event = JsonUtils.parseObject(responseEvent.getResult(), EventVo.class);
                    FinanceServiceImpl.sendSmsForFail(orgId,"CK_PULL_PAY_BILL", orgName, date, YYYYMMDDHHMISS14.format(new Date()),event.getEventLevel()+"","拉取alipay对账文件出现异常："+e.getMessage());
                }
                else {
                    logger.error("获取系统事件定义事事件，无法获取事件级别：CK_PULL_PAY_BILL");
                    FinanceServiceImpl.sendSmsForFail(orgId,"CK_PULL_PAY_BILL",orgName, date, YYYYMMDDHHMISS14.format(new Date()),"-1","拉取alipay对账文件出现异常："+e.getMessage());
                }

                FinanceServiceImpl.insertLog(orgId, "CK_PULL_PAY_BILL",JsonUtils.toJsonString(mapReturn));
            }
        }else if("1".equals(payMode.toString().substring(0,1)) && paymentSetting.getEnableFlag() == 1){
            map.put("payKey",payKey);
            map.put("mchId",paymentSetting.getMerchantAccount());

            try {
                //获取微信数据
                Response resp = PayService.callHumpFromInternal(MethodRouter.WECHAT_CHECK_PAYMENT_PLATFORM, JSON.toJSONString(map));
                logger.info("wechat调用："+JsonUtils.toJsonString(resp));

                Map <String,String> amap =null;
                if("0".equals(resp.getResultCode())){
                    amap = JSON.parseObject(resp.getResult(), Map.class);
                }

                if (StringUtils.isNotBlank(resp.getResult())) {
                 	mapReturn = JsonUtils.parseObject(resp.getResult());
                 }
                if(!"0".equals(resp.getResultCode()) && !"51001".equals(resp.getResultCode())){
                	getDataFlag = false;
                    logger.error(orgName + "拉取wechat账单失败！ -- " + resp.getResultMessage());
                    response.setResultCodeAndMessage(Response.FAILURE_CODE , "拉取wechat账单失败！");
                }else if("51001".equals(resp.getResultCode())){
                	getDataFlag = true;
                    logger.error(orgName + " -- " + resp.getResultMessage());
                    response.setResultCodeAndMessage(Response.SUCCESS_CODE , resp.getResultMessage());
                }else{
                	getDataFlag = true;
                    Map <String,String> wmap = JSON.parseObject(resp.getResult(), Map.class);
                    count = wmap.get("count");

                    List<OrderCheckedExceptionVo> exVos = new ArrayList<OrderCheckedExceptionVo>();
                    List<PaymentCheckSourceFileVo> payVos = new ArrayList<PaymentCheckSourceFileVo>();

                    //当天账单根据订单号查询Order表
                    map = new HashMap<>();
                    map.put("pay_time",date);
                    map.put("pay_app_id",appId);
                    resp = checkPaymentService.getCheckPayment(JSON.toJSONString(map));
                    if("0".equals(resp.getResultCode())){
                        List<PaymentCheckSourceFileVo> vos = JsonUtils.parseArray(resp.getResult(), PaymentCheckSourceFileVo.class);
                        for (PaymentCheckSourceFileVo co : vos) {
                            map = new HashMap<>();
                            map.put("order_no", co.getOrderNo());
                            Response res = BaseService.callHumpFromInternal(MethodRouter.BASE_FIND_ORDER, JSON.toJSONString(map));
                            if("0".equals(res.getResultCode())){
                                map = JsonUtils.parseObject(res.getResult(), Map.class);
                                co.setPlatformId(map.get("platform_id"));
                                co.setPlatformName(map.get("platform_name"));
                                co.setPlatformCode(map.get("platform_code"));
                                co.setPlatformOrgAppCode(map.get("platform_org_app_code"));
                                co.setPlatformOrgAppName(map.get("platform_org_app_name"));
                                co.setOrgId(map.get("org_id"));
                                co.setOrgName(map.get("org_name"));
                                co.setOrgCode(map.get("org_code"));
                                payVos.add(co);
                            }else{
                                OrderCheckedExceptionVo orderException = new OrderCheckedExceptionVo();
                                orderException.setId(UUIDUtil.get32UUID());
                                orderException.setOrderNo(co.getOrderNo());
                                orderException.setOrgId(orgId);
                                orderException.setPayAppId(co.getPayAppId());
                                orderException.setPayTime(co.getPayTime());
                                orderException.setExceptionType((short) 1);
                                orderException.setExceptionReason(orgName + " 订单号：" + co.getOrderNo() + " 订单不存在！！");
                                orderException.setCreatedBy("三方对账平台");
                                orderException.setCreatedTime(sdf.format(new Date()));
                                exVos.add(orderException);
                                throw new RuntimeException(orgName + " 订单号：" + co.getOrderNo() + ",该订单在Order表不存在！！");
                            }
                        }
                    }

                    //执行修改数据
                    resp = checkPaymentService.updateCheckPayment(JSON.toJSONString(payVos));

                    if(exVos.size() > 0){
                        checkPaymentService.addCheckPaymentToException(JSON.toJSONString(exVos));
                    }
                    if("0".equals(resp.getResultCode())){
                    	logger.info(orgName + appId +"入库完毕！---wechat入库数："+ count +",返回信息：" + resp.getResultMessage());
                        inputAndCheckPaymentsFlag = true;
                    }
                    else {
                    	logger.error("updateCheckPayment异常");
                    }

                }
            } catch (Exception e) {
            	exceptionFlag = true;
            	mapReturn.put("inputAndCheckPayments", "拉取wechat对账文件出现异常："+e.getMessage());
                logger.error("[PaymentCheckRunnable.checkPayments.wechat]" + orgName, e);
                //事件信息
                Map<String,Object> paramEvent = new HashMap<>();
                paramEvent.put("event_code", "CK_PULL_PAY_BILL");
                paramEvent.put("module_code", "CHECK_ACCOUNT");
                Response responseEvent = BaseService.callHumpFromInternal("yyt.base.event.get", JsonUtils.toJsonString(paramEvent));
                if (StringUtils.isNotBlank(responseEvent.getResult())) {
                    EventVo event = JsonUtils.parseObject(responseEvent.getResult(), EventVo.class);
                    FinanceServiceImpl.sendSmsForFail(orgId,"CK_PULL_PAY_BILL", orgName, date, YYYYMMDDHHMISS14.format(new Date()),event.getEventLevel()+"","拉取wechat对账文件出现异常："+e.getMessage());
                }
                else {
                    logger.error("获取系统事件定义事事件，无法获取事件级别：CK_PULL_PAY_BILL");
                    FinanceServiceImpl.sendSmsForFail(orgId,"CK_PULL_PAY_BILL",orgName, date, YYYYMMDDHHMISS14.format(new Date()),"-1","拉取wechat对账文件出现异常："+e.getMessage());
                }

                FinanceServiceImpl.insertLog(orgId, "CK_PULL_PAY_BILL",JsonUtils.toJsonString(mapReturn));
            }
        }
        
        mapReturn.put("org_id",orgId);
        mapReturn.put("orgName",orgName);
        mapReturn.put("appId",appId);
        mapReturn.put("date",date);
        mapReturn.put("check_data_type","third");
        
        mapReturn.put("inputAndCheckPaymentsFlag",inputAndCheckPaymentsFlag);
        
        String resultCode = "-1";
        String resultMessage = "出错";
        if (getDataFlag && ( ! exceptionFlag)) {
        	resultCode = "0";
        	resultMessage = "成功";
        }
        response = new Response(resultCode,resultMessage,JsonUtils.toJsonString(mapReturn));

        return response;
    }

}
